-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: remove ipfs dependencies #167
Conversation
WalkthroughThis pull request introduces significant changes to the handling of group metadata across multiple components. The modifications primarily focus on improving error handling, data parsing, and metadata retrieval. Key changes include the removal of IPFS-related functionality, updates to data structures using SDK types, and the implementation of more robust parsing of group metadata. The changes streamline the approach to handling group information, eliminating direct IPFS metadata dependencies and introducing more consistent error handling across components. Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (10)
components/groups/modals/groupDetailsModal.tsx (3)
49-49
: Authors Field Display
Displaying authors in a simple paragraph works, but if multiple authors are common, consider rendering them in a list for improved readability.
61-61
: Details Field
For very long details, consider adding truncation or a "Show More" toggle to maintain a tidy UI.
67-67
: Proposal Forum URL
If the URL is meant to be clickable, consider wrapping it in an anchor tag to facilitate navigation.components/groups/modals/groupInfo.tsx (2)
122-131
: Mapping Authors to UI
Mapping either addresses or plain text authors is done cleanly. For improved readability, consider a dedicated function or component.
167-171
: Centralized Metadata Parsing
Reusing JSON.parse for group metadata. Consider moving reptitive parse logic into a shared utility if it appears in multiple places.components/groups/modals/updateGroupModal.tsx (1)
34-39
: Leverage user-facing error handling for JSON parse failures
Catching JSON parse errors and logging them is helpful. However, consider providing a user-facing notification or fallback UI message (e.g., “Metadata is invalid or unavailable”) to ensure clarity for non-technical users.components/groups/components/myGroups.tsx (3)
57-66
: Keep filter logic lightweight for large group lists
While this inline JSON parsing is acceptable for small to medium datasets, you may want to parse and cache metadata once per group to avoid repeatedly parsing the same JSON string whenever the filter runs (especially for large numbers of groups).
82-93
: Fallback name handling
Logging a warning and falling back to 'Untitled Group' is a good strategy for resilience. If the group name is crucial for user workflow, consider surfacing a more visible notification that the metadata is invalid.
470-476
: Consistent approach to invalid metadata
Again, the fallback to 'Untitled Group' ensures consistent UX. Maintain consistency across components by employing a shared helper function to parse metadata and extract a valid name.hooks/useQueries.ts (1)
131-131
: Robust concurrency handling
Using Promise.all for policy and member results is a good approach. Ensure partial or individual promise failures don’t halt the entire fetch process if you want to retrieve data for other groups. Currently, the try/catch block handles overall failures, but a more granular error handling might be beneficial if partial data is acceptable.Also applies to: 138-138
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
components/groups/components/myGroups.tsx
(3 hunks)components/groups/forms/groups/ConfirmationForm.tsx
(1 hunks)components/groups/forms/groups/MemberInfoForm.tsx
(1 hunks)components/groups/modals/groupDetailsModal.tsx
(6 hunks)components/groups/modals/groupInfo.tsx
(4 hunks)components/groups/modals/updateGroupModal.tsx
(1 hunks)components/groups/modals/voteDetailsModal.tsx
(1 hunks)components/wallet.tsx
(1 hunks)hooks/index.tsx
(0 hunks)hooks/useIpfs.ts
(0 hunks)hooks/useQueries.ts
(2 hunks)
💤 Files with no reviewable changes (2)
- hooks/index.tsx
- hooks/useIpfs.ts
✅ Files skipped from review due to trivial changes (1)
- components/groups/modals/voteDetailsModal.tsx
🔇 Additional comments (20)
components/groups/modals/groupDetailsModal.tsx (7)
2-6
: Clean Import of SDK Types
These imports neatly align with the removal of IPFS-based dependencies. Inlining the types from '@liftedinit/manifestjs' is consistent with the new metadata approach.
13-14
: Updated Data Structure for Members and Policies
Defining members and policies as typed arrays is a robust improvement, eliminating the reliance on IPFS metadata.
31-35
: Consistent Field Extraction
Using fallback strings ensures resilience if metadata fields are missing. This keeps the UI stable and user-friendly.
55-55
: Summary Field
Straightforward approach to show the summary. This looks good.
108-110
: Threshold Display
Combining the threshold with the group members count is intuitive. Ensure the member count’s accuracy if membership changes dynamically.
165-170
: Admin Access Checks
The multi-condition logic correctly identifies super admins, policy-only admins, and group-only admins. Nicely handled.
90-97
: Voting Period Calculation
Using parseInt and dividing by 86400 is valid. Verify that the seconds property is always defined to avoid NaN issues.
components/groups/forms/groups/ConfirmationForm.tsx (1)
66-66
: Directly Setting Group Metadata
Removing IPFS upload and assigning the JSON string directly to groupMetadata simplifies the flow, aligning with the PR’s objective to remove IPFS dependencies.
components/wallet.tsx (1)
216-217
: Simplified OnClick Logic
Assigning the same onClick references for Disconnected/Rejected states yields a more concise flow.
components/groups/modals/groupInfo.tsx (9)
87-95
: Robust JSON Parsing for Authors
Wrapping JSON.parse in a try-catch safeguards the component from malformed group metadata.
101-104
: Helper to Format Address
Extracting a small helper for rendering addresses improves clarity and maintainability.
106-108
: Helper to Format Author
A parallel helper function for authors keeps the code base consistent.
110-114
: Conditional Address Detection
Checking if a string starts with 'manifest1' is an effective way to differentiate addresses from plain text.
117-119
: Filtering Manifest Addresses
This simple filter ensures that only recognized addresses are treated specially.
133-133
: Catch Potential Errors
Warning logs on parse failure help diagnose metadata issues without crashing the UI.
164-166
: Default Fallback for Title and Details
Setting defaults ensures the UI remains stable if metadata lacks these fields.
203-203
: Modal Title
Now referencing the parsed title variable, so it’s consistent with other metadata-driven fields.
244-244
: Utilizing Details
Using the “details” variable ensures the description is displayed consistently.
components/groups/forms/groups/MemberInfoForm.tsx (1)
250-250
: Providing Current Address to the Modal
Passing the current address as a prop helps the modal manage or display user-specific data effectively.
components/groups/modals/updateGroupModal.tsx (1)
41-45
: Good use of safe property access
Providing default empty strings ensures that the UI remains stable if any of these metadata fields are missing or invalid. This guards against runtime errors and unexpected UI crashes.
Hey @chalabi2, can you fix the conflict, please? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: Joseph Chalabi <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
components/groups/forms/groups/GroupDetailsForm.tsx (1)
52-56
: Consider adjusting description field validation constraints.The current validation rules for the description field might be too restrictive:
- Minimum length of 50 characters could be excessive for simple groups
- Maximum length of 100 characters might be too limiting for detailed group descriptions
Consider relaxing these constraints, for example:
- .min(50, 'Description must be at least 50 characters') - .max(100, 'Description must not exceed 100 characters') + .min(20, 'Description must be at least 20 characters') + .max(200, 'Description must not exceed 200 characters')components/groups/modals/groupDetailsModal.tsx (2)
90-97
: Simplify voting period calculation.The current implementation involves multiple type assertions and nested property access.
Consider extracting the logic into a helper function:
const getVotingPeriodInDays = (policy: GroupPolicyInfoSDKType): string => { const decisionPolicy = policy?.decision_policy as ThresholdDecisionPolicySDKType; const seconds = decisionPolicy?.windows?.voting_period?.seconds?.toString() ?? '0'; return Math.floor(parseInt(seconds) / 86400).toString(); };
165-170
: Improve readability of admin status checks.The nested ternary operators make the code harder to read and maintain.
Consider using a more readable approach:
const getAdminStatus = (address: string): React.ReactNode => { const isSuperAdmin = isPolicyAdmin(address) && isAdmin(address); const isPolicyAdminOnly = isPolicyAdmin(address) && !isAdmin(address); const isGroupAdminOnly = !isPolicyAdmin(address) && isAdmin(address); if (isSuperAdmin) return 'Super Admin'; if (isPolicyAdminOnly) return 'Policy'; if (isGroupAdminOnly) return 'Group'; return <PiXCircleLight className="text-red-500 h-5 w-5" />; };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
components/groups/forms/groups/GroupDetailsForm.tsx
(1 hunks)components/groups/modals/groupDetailsModal.tsx
(6 hunks)components/groups/modals/updateGroupModal.tsx
(6 hunks)components/wallet.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- components/wallet.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
components/groups/modals/updateGroupModal.tsx
[error] 242-242: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 247-247: Do not add then to an object.
(lint/suspicious/noThenProperty)
🔇 Additional comments (4)
components/groups/forms/groups/GroupDetailsForm.tsx (1)
58-68
: LGTM! Essential metadata length validation.The metadata length test is crucial as it ensures the total serialized metadata doesn't exceed 255 characters, preventing potential issues with metadata storage.
components/groups/modals/groupDetailsModal.tsx (1)
29-40
: LGTM! Robust metadata parsing with error handling.The implementation safely handles JSON parsing with proper error handling and fallback values.
components/groups/modals/updateGroupModal.tsx (2)
34-39
: LGTM! Robust metadata parsing with error handling.The implementation safely handles JSON parsing with proper error handling and console warning.
268-279
: LGTM! Comprehensive voting period validation.The validation ensures a minimum voting period of 30 minutes, which is a good safeguard against too short voting windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
components/groups/modals/updateGroupModal.tsx (1)
Line range hint
385-394
: Fix inconsistency between input maxLength and validationThe
maxLength
prop on the name input (24) doesn't match the validation schema's max length (50).<TextInput label="Group Name" name="name" placeholder="Group Name" value={values.name} onChange={(e: React.ChangeEvent<HTMLInputElement>) => { setName(e.target.value); setFieldValue('name', e.target.value); }} - maxLength={24} + maxLength={50} />
🧹 Nitpick comments (3)
components/groups/modals/updateGroupModal.tsx (3)
34-39
: Enhance error logging for metadata parsing failuresThe current error handling could be more informative for debugging purposes.
try { maybeMetadata = group.metadata ? JSON.parse(group.metadata) : null; } catch (e) { - console.warn('Failed to parse group metadata:', e); + console.warn( + `Failed to parse group metadata for group ${group.id}:`, + '\nRaw metadata:', group.metadata, + '\nError:', e + ); }
Line range hint
95-157
: Consider refactoring message building logic for better maintainabilityThe message building logic contains repeated patterns and complex conditions that could be simplified.
Consider extracting message creation into helper functions:
const createMessage = (typeUrl: string, value: Uint8Array): Any => { return Any.fromPartial({ typeUrl, value, }); }; const buildMetadataMessage = (newMetadata: string) => { const messages: Any[] = []; // Group metadata const msgGroupMetadata = updateGroupMetadata({ admin: group.admin, groupId: BigInt(maybeMembers?.[0]?.group_id), metadata: newMetadata, }); messages.push(createMessage( cosmos.group.v1.MsgUpdateGroupMetadata.typeUrl, cosmos.group.v1.MsgUpdateGroupMetadata.encode(msgGroupMetadata.value).finish() )); // Policy metadata const msgPolicyMetadata = updateGroupPolicyMetadata({ groupPolicyAddress: maybePolicies?.address, admin: group.admin, metadata: newMetadata, }); messages.push(createMessage( cosmos.group.v1.MsgUpdateGroupPolicyMetadata.typeUrl, cosmos.group.v1.MsgUpdateGroupPolicyMetadata.encode(msgPolicyMetadata.value).finish() )); return messages; };
223-292
: Enhance metadata length validationWhile the total metadata length validation is good, it should include all fields and provide more precise feedback.
.test( 'metadata-total-length', 'Total metadata length must not exceed 255 characters', function (values) { const metadata = JSON.stringify({ title: values.name || '', authors: values.authors || '', + summary: values.summary || '', details: values.description || '', }); - return metadata.length <= 255; + const remaining = 255 - metadata.length; + return this.createError({ + message: remaining < 0 + ? `Metadata exceeds limit by ${Math.abs(remaining)} characters` + : true + }); } );🧰 Tools
🪛 Biome (1.9.4)
[error] 242-242: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 247-247: Do not add then to an object.
(lint/suspicious/noThenProperty)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
components/groups/modals/updateGroupModal.tsx
(6 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
components/groups/modals/updateGroupModal.tsx
[error] 242-242: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 247-247: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
components/groups/modals/updateGroupModal.tsx (1)
41-44
: LGTM! Clean removal of IPFS dependenciesThe state initialization properly handles the transition from IPFS metadata to direct JSON parsing with appropriate fallbacks.
Also applies to: 59-59
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm.
The SDK documentation also specifies that the metadata field can be
any of base64 encoded, raw text, stringified json, IPFS link to json
The Manifest App only supports stringified json
as of now. Optional support for the rest could be added after launch.
The good news is the manifest chain metadata max length is 10000 chars 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
components/groups/modals/updateGroupModal.tsx (4)
34-39
: Enhance error handling for metadata parsing.While the try-catch block is good, consider adding more context to the warning message and implementing proper error recovery.
try { maybeMetadata = group.metadata ? JSON.parse(group.metadata) : null; } catch (e) { - console.warn('Failed to parse group metadata:', e); + console.warn(`Failed to parse group metadata for group ${group.id}:`, { + error: e, + metadata: group.metadata + }); + // Consider notifying the user about the parsing error }
223-268
: Consider extracting validation constants and simplifying conditions.The validation schema is complex with nested conditions. Consider extracting constants and simplifying the structure.
// Extract to constants const MAX_NAME_LENGTH = 50; const MAX_AUTHORS_LENGTH = 50; const MIN_DESCRIPTION_LENGTH = 20; const MAX_DESCRIPTION_LENGTH = 100; const MIN_VOTING_PERIOD_MINUTES = 30; // Simplified validation const validationSchema = Yup.object().shape({ name: Yup.string() .max(MAX_NAME_LENGTH) .noProfanity() .when(['threshold', 'votingPeriod'], { is: hasThresholdOrVotingPeriodChanges, then: schema => schema.optional(), otherwise: schema => schema.when(['authors', 'summary', 'description'], { is: hasNoMetadataChanges, then: schema => schema.required('At least one metadata field is required'), otherwise: schema => schema.optional(), }), }), // ... rest of the validation });🧰 Tools
🪛 Biome (1.9.4)
[error] 242-242: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 247-247: Do not add then to an object.
(lint/suspicious/noThenProperty)
232-239
: Extract duplicated voting period calculations.The voting period calculations are duplicated in multiple places. Consider extracting this logic into a utility function.
// Extract to a utility function const calculateTotalSeconds = (period: { days: number; hours: number; minutes: number; seconds: number }) => { return (Number(period.days) || 0) * 86400 + (Number(period.hours) || 0) * 3600 + (Number(period.minutes) || 0) * 60 + (Number(period.seconds) || 0); };Also applies to: 306-314
Line range hint
177-196
: Enhance error handling and user feedback during form submission.The error handling during form submission could provide better user feedback.
} catch (error) { console.error('Error in handleConfirm:', error); setIsSigning(false); + // Provide user-friendly error message + const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred'; + alert(errorMessage); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/groups/forms/groups/GroupDetailsForm.tsx
(1 hunks)components/groups/modals/updateGroupModal.tsx
(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- components/groups/forms/groups/GroupDetailsForm.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
components/groups/modals/updateGroupModal.tsx
[error] 242-242: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 247-247: Do not add then to an object.
(lint/suspicious/noThenProperty)
'metadata-total-length', | ||
'Total metadata length must not exceed 100000 characters', | ||
function (values) { | ||
const metadata = JSON.stringify({ | ||
title: values.name ?? '', | ||
authors: values.authors ?? '', | ||
details: values.description ?? '', | ||
}); | ||
return metadata.length <= 10000; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix inconsistent metadata length limit.
The error message states 100000 characters but the validation checks against 10000 characters.
.test(
'metadata-total-length',
- 'Total metadata length must not exceed 100000 characters',
+ 'Total metadata length must not exceed 10000 characters',
function (values) {
const metadata = JSON.stringify({
title: values.name ?? '',
authors: values.authors ?? '',
details: values.description ?? '',
});
return metadata.length <= 10000;
}
);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
'metadata-total-length', | |
'Total metadata length must not exceed 100000 characters', | |
function (values) { | |
const metadata = JSON.stringify({ | |
title: values.name ?? '', | |
authors: values.authors ?? '', | |
details: values.description ?? '', | |
}); | |
return metadata.length <= 10000; | |
} | |
.test( | |
'metadata-total-length', | |
'Total metadata length must not exceed 10000 characters', | |
function (values) { | |
const metadata = JSON.stringify({ | |
title: values.name ?? '', | |
authors: values.authors ?? '', | |
details: values.description ?? '', | |
}); | |
return metadata.length <= 10000; | |
} | |
) |
Remove IPFS dependencies
Fixes #159
Summary by CodeRabbit
Release Notes
New Features
currentAddress
property to theTailwindModal
inMemberInfoForm
.Bug Fixes
Chores
Style
VoteDetailsModal
for better usability.These changes enhance the overall user experience by improving data handling and interface consistency.